﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using xplang.abstractions;
using xplang.run;

namespace xplang.rtl.native
{
  public class StringClass : NativeClass
  {

    internal StringClass()
      : base(RTL.rtl, "String")
    {
      genericParams = new GenericParamDecl[] { };
      ClassRef _this = getRef(null);
      inheritance = new ClassRef[]{
        xplang.rtl.RTL.equatableClass.getRef(new ClassRef[]{_this}),
        xplang.rtl.RTL.comparableClass.getRef(new ClassRef[]{_this}),
        xplang.rtl.RTL.addableClass.getRef(new ClassRef[]{_this}),
        xplang.rtl.RTL.incrementableClass.getRef(null),
        xplang.rtl.RTL.decrementableClass.getRef(null)
      };
    }

    public override void registerMembers()
    {
      xplang.rtl.RTL.comparableClass.mGE.registerImplementation(this, execGE);
      xplang.rtl.RTL.comparableClass.mGT.registerImplementation(this, execGT);
      xplang.rtl.RTL.comparableClass.mLE.registerImplementation(this, execLE);
      xplang.rtl.RTL.comparableClass.mLT.registerImplementation(this, execLT);

      xplang.rtl.RTL.addableClass.mAdd.registerImplementation(this, execAdd);
    }

    public Value execGE(Value[] heap, ref FlowState state)
    {
      String l = (String)(heap[0].pointer);
      String r = (String)(heap[1].pointer);
      return new Value(xplang.rtl.RTL.booleanClass.getRef(null), String.CompareOrdinal(l, r) >= 0);
    }

    public Value execGT(Value[] heap, ref FlowState state)
    {
      String l = (String)(heap[0].pointer);
      String r = (String)(heap[1].pointer);
      return new Value(xplang.rtl.RTL.booleanClass.getRef(null), String.CompareOrdinal(l, r) > 0);
    }

    public Value execLE(Value[] heap, ref FlowState state)
    {
      String l = (String)(heap[0].pointer);
      String r = (String)(heap[1].pointer);
      return new Value(xplang.rtl.RTL.booleanClass.getRef(null), String.CompareOrdinal(l, r) <= 0);
    }

    public Value execLT(Value[] heap, ref FlowState state)
    {
      String l = (String)(heap[0].pointer);
      String r = (String)(heap[1].pointer);
      return new Value(xplang.rtl.RTL.booleanClass.getRef(null), String.CompareOrdinal(l, r) < 0);

    }

    public Value execAdd(Value[] heap, ref FlowState state)
    {
      String l = (String)(heap[0].pointer);
      String r = (String)(heap[1].pointer);
      return new Value(xplang.rtl.RTL.stringClass.getRef(null), l + r);
    }

    public override object newInstance()
    {
      return new String(' ', 0);
    }

    public override Value getAttributeValue(Value _this, Variable variable)
    {
      throw new NotImplementedException();
    }

    public override void setAttributeValue(Value _this, Variable variable, Value obj)
    {
      throw new NotImplementedException();
    }
  }
}
